﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////


#pragma once
#include "GcmpDwgDxfInterface.h"
#include "GbmpTypeDefs.h"
#include "Vector2d.h"
#include "Color.h"
#include "Matrix4d.h"

namespace gcmp
{
    /// \brief PDF导出图形方向
    enum class PDFPlotRotation : int32_t
    {
        Degrees0 = 0, ///< 0度
        Degrees90 = 1,///< 90度
        Degrees180 = 2,///< 180度
        Degrees270 = 3///< 270度
    };

    /// \brief PDF打印区域/打印范围
    enum class PDFPlotType : int32_t
    {
        Display = 0,  ///< 打印绘图区域中显示的所有对象
        Extents = 1,  ///< 打印图形中的所有对象。GCMP内部计算出当前图纸空间的【打印矩形范围】
        Window = 2,   ///< 用户框选一个区域打印。
        Layout = 3    ///< 打印当前图纸空间的范围
    };

    /// \brief PDF颜色策略
    enum class PDFColorPolicy : int32_t
    {
        NoPolicy = 0,   ///< 无颜色策略，彩色
        Monochrome = 1, ///< 单色，黑白色
        Grayscale = 2   ///< 灰度
    };

    /// \brief PDF打印比例
    enum class PDFStdScaleType : int32_t
    {
        ScaleToFit = 0, ///< Scaled to Fit
        Scale_1_1 = 1, ///< 1:1
        Scale_1_2 = 2, ///< 1:2
        Scale_1_4 = 3, ///< 1:4
        Scale_1_5 = 4, ///< 1:5
        Scale_1_8 = 5, ///< 1:8
        Scale_1_10 = 6, ///< 1:10
        Scale_1_16 = 7, ///< 1:16
        Scale_1_20 = 8, ///< 1:20
        Scale_1_30 = 9, ///< 1:30
        Scale_1_40 = 10, ///< 1:40
        Scale_1_50 = 11, ///< 1:50
        Scale_1_100 = 12, ///< 1:100
        Scale_2_1 = 13, ///< 2:1
        Scale_4_1 = 14, ///< 4:1
        Scale_8_1 = 15, ///< 8:1
        Scale_10_1 = 16, ///< 10:1
        Scale_100_1 = 17, ///< 100:1
        Scale_1000_1 = 18, ///< 1000:1
    };

    /// \brief 原SetZoomToExtendPaper/GetZoomToExtendPaper已经废弃，该结构体实际不能使用
    struct GCMP_DWG_DXF_INTERFACE_EXPORT ZoomToExtendPaper
    {
        double width;
        double height;
        ZoomToExtendPaper() :width(0.), height(0.) {}
        bool operator==(const ZoomToExtendPaper& paper) const
        {
            return width == paper.width
                && height == paper.height;
        }
    };

    /// \brief 设置标准纸张4个边距
    struct GCMP_DWG_DXF_INTERFACE_EXPORT StdPaperMargins
    {
        double left;//纸张左边距
        double top;//纸张上边距
        double right;//纸张右边距
        double bottom;//纸张下边距
        StdPaperMargins() :left(0.), top(0.), right(0.), bottom(0.){}
        bool operator==(const StdPaperMargins& paper) const
        {
            return left == paper.left
                && top == paper.top
                && right == paper.right
                && bottom == paper.bottom;
        }
    };

    /// \brief PDF打印自定义图纸大小
    struct GCMP_DWG_DXF_INTERFACE_EXPORT CustomPaperInfo
    {
        std::wstring canonicalName;//自定义图纸名称
        std::wstring localeName;//自定义图纸别名

        double width;//纸张宽度
        double height;//纸张高度

        double left;//纸张左边距
        double top;//纸张上边距
        double right;//纸张右边距
        double bottom;//纸张下边距

        CustomPaperInfo()
            : canonicalName(L"test")
            ,localeName(L"test")
            ,width(0.)
            , height(0.)
            , left(-(std::numeric_limits<double>::max)())
            , top(-(std::numeric_limits<double>::max)())
            , right(-(std::numeric_limits<double>::max)())
            , bottom(-(std::numeric_limits<double>::max)())
        {
        }

        bool operator==(const CustomPaperInfo& p) const
        {
            return  canonicalName == p.canonicalName
                && localeName == p.localeName
                && width == p.width
                && height == p.height
                && left == p.left
                && top == p.top
                && right == p.right
                && bottom == p.bottom;
        }
    };

    /// \brief pdf转图片 输入参数
    struct GCMP_DWG_DXF_INTERFACE_EXPORT Pdf2ImageConversionParams
    {
        Color  BackGroundColor = Color::White;  // 背景色
        UInt16  DPI = 72;                       // dpi (0,3000]
    };

    /// \brief pdf转图片 结果参数
    struct GCMP_DWG_DXF_INTERFACE_EXPORT Pdf2ImageResultParams
    {
        UInt32 PixelHeight = 0;                 // 图片像素 高
        UInt32 PixelWidth = 0;                  // 图片像素 宽
    };

    /// \brief PDF导出参数基类 
    /// 
    /// 包括分辨率，颜色策略，pdf格式，填充类型，导出标记位，自适应纸张大小
    /// 视口，缩放比例，窗口范围，旋转角度，打印区域类型，打印偏移，是否居中，打印纸张大小，设置打印机/绘图仪，自定义图纸尺寸等
    /// pdf参数说明 https://km.glodon.com/pages/viewpage.action?pageId=127836401
    /// 需求文档 https://km.glodon.com/pages/viewpage.action?pageId=150579740
    class GCMP_DWG_DXF_INTERFACE_EXPORT IPDFExportParams
    {
    public:
        IPDFExportParams();
        /// \brief 创建PDF导出参数。
        /// 
        /// \return 返回创建PDF导出的对象。
        static OwnerPtr<IPDFExportParams> Create();

        /// \brief 设置导出的矢量分辨率
        /// \param geomRes分辨率大小
        virtual void SetGeometryResolution(UInt16 geomRes) = 0;

        /// \brief 导出的矢量分辨率
        /// 
        /// \return 返回UInt16,分辨率大小
        virtual UInt16 GetGeometryResolution() const = 0;

        /// \brief 设置导出的颜色分辨率
        /// \param colorRes分辨率大小
        virtual void SetColorResolution(UInt16 colorRes) = 0;

        /// \brief 导出的颜色分辨率
        /// 
        /// \return 返回UInt16,分辨率大小
        virtual UInt16 GetColorResolution() const = 0;

        /// \brief 设置导出的单色图像分辨率
        /// \param monoRes分辨率大小
        virtual void SetMonochromeResolution(UInt16 monoRes) = 0;

        /// \brief 导出的单色图像分辨率
        /// 
        /// \return 返回UInt16,分辨率大小
        virtual UInt16 GetMonochromeResolution() const = 0;

        /// \brief 设置是否自适应
        /// \param zoomToExtend 为true是自适应纸张大小，false不自适应
        /// 为true时和ZoomToExtendPaper配合使用
        virtual void SetIsZoomToExtend(bool zoomToExtend) = 0;

        /// \brief 得到是否自适应
        /// 
        /// \return bool,为true是自适应纸张大小，false不自适应
        virtual bool IsZoomToExtend() const = 0;

#pragma region 标准纸张边距

        /// \brief 设置默认图纸的4个页边界
        /// \param[in] paperMargin 纸张的边距
        virtual void SetStdPaperMargins(const StdPaperMargins& paperMargin) = 0;

        /// \brief 得到默认图纸的4个页边界
        /// \return 返回页边距
        virtual StdPaperMargins GetStdPaperMargins() const = 0;
#pragma endregion

#pragma region plotSetting
        /// \brief 设置缩放比例
        /// \param stdScaleType 缩放比例
        virtual void SetStdScaleType(const PDFStdScaleType& stdScaleType) = 0;

        /// \brief 返回缩放比例
        /// 
        /// \return 返回PDFStdScaleType,缩放比例
        virtual PDFStdScaleType GetStdScaleType() const = 0;

        /// \brief 设置自定义打印比例，两个参数要求为正数
        /// \param[in]  numerator       纸张上的单位数(分子)
        /// \param[in]  denominator     平台上的单位数（分母）
        /// \return 返回true，设置成功；否则设置失败
        virtual bool SetCustomPrintScale(double numerator, double denominator) = 0;

        /// \brief 返回自定义打印比例
        /// \param[out] numerator       纸张上的单位数(分子)
        /// \param[out] denominator     平台上的单位数（分母） 
        virtual void GetCustomPrintScale(double& numerator, double& denominator) const = 0;

        /// \brief 返回是否使用了标准打印比例
        /// 
        /// \return 返回true 使用了标准打印比例，返回false 则使用了自定义打印比例
        virtual bool IsUseStandardScale() const = 0;

        /// \brief 设置窗口范围，在PDFPlotType为Windows模式下可设置显示窗口区域
        /// \param xMin yMin窗口左下角，xMax yMax窗口右上角
        virtual void SetPlotWindowArea(double xMin, double yMin, double xMax, double yMax) = 0;

        /// \brief 得到窗口范围
        /// 
        /// \return 返回xMin yMin窗口左下角，xMax yMax窗口右上角
        virtual void GetPlotWindowArea(double& xMin, double& yMin, double& xMax, double& yMax) const = 0;

        /// \brief 设置旋转角度
        /// \param plotRotation 旋转角度
        virtual void SetPlotRotation(const PDFPlotRotation& plotRotation) = 0;

        /// \brief 得到旋转角度
        /// 
        /// \return 返回PDFPlotRotation旋转角度
        virtual PDFPlotRotation GetPlotRotation() const = 0;

        /// \brief 设置打印区域类型
        /// \param plotType 打印区域类型
        virtual void SetPlotType(const PDFPlotType& plotType) = 0;

        /// \brief 得到打印区域类型
        /// 
        /// \return 返回PDFPlotType打印区域类型
        virtual PDFPlotType GetPlotType() const = 0;

        /// \brief 设置打印颜色策略
        /// \param colorPolicy 打印颜色策略
        virtual void SetColorPolicy(const PDFColorPolicy& colorPolicy) = 0;

        /// \brief 得到打印颜色策略
        /// 
        /// \return 返回PDFColorPolicy打印颜色策略
        virtual PDFColorPolicy GetColorPolicy() const = 0;

        /// \brief 设置是否支持图层输出到pdf
        /// \param  enableLayers,true支持图层输出到pdf，false不支持
        virtual void SetEnableLayers(bool enableLayers) = 0;

        /// \brief 得到是否支持图层输出到pdf
        /// 
        /// \return bool,为true支持图层输出，false不支持
        virtual bool GetEnableLayers() const = 0;
        
        /// \brief 设置打印偏移
        /// \param offset 偏移
        virtual void SetPlotOriginOffset(const gcmp::Vector2d& offset) = 0;

        /// \brief 得到打印偏移
        /// 
        /// \return 返回gcmp::Vector2d打印偏移
        virtual gcmp::Vector2d GetPlotOriginOffset() const = 0;

        /// \brief 设置打印居中
        /// \param plotCentered 是否居中
        virtual void SetPlotCentered(bool plotCentered) = 0;

        /// \brief 得到是否打印居中
        /// 
        /// \return 返回是否打印居中 true居中
        virtual bool PlotCentered() const = 0;

        /// \brief 设置打印纸张大小，打印设备不是Comstom Device的情况下，使用内置打印纸张大小的名称
        /// \param mediaName 纸张大小对应的字符串
        virtual void SetMediaName(std::wstring mediaName) = 0;

        /// \brief 得到打印纸张大小
        /// \return 返回是纸张大小对应的字符串
        virtual std::wstring GetMediaName() const = 0;

        /// \brief 设置打印机/绘图仪，自定义纸张大小的设备名称为Comstom Device
        /// \param deviceName 打印机名称
        virtual void SetPlotDeviceName(std::wstring deviceName) = 0;

        /// \brief 得到打印机/绘图仪名称
        /// \return 返回打印机名称
        virtual std::wstring GetPlotDeviceName() const = 0;

        /// \brief 设置自定义图纸，当打印设备为Comstom Device的情况下，用户可以自定义纸张大小
        /// \param paperInfo 自定义图纸信息
        virtual void SetCustomPaperInfo(const CustomPaperInfo& paperInfo) = 0;

        /// \brief 得到自定义图纸
        /// \return 返回自定义图纸
        virtual CustomPaperInfo GetCustomPaperInfo() const = 0;

        /// \brief 设置SHX文字几何化
        /// \param bAsGeometry true几何化
        virtual void SetSHXTextAsGeometry(bool bAsGeometry) = 0;

        /// \brief 得到SHX文字是否几何化
        /// \return 返回SHX文字是否几何化
        virtual bool GetSHXTextAsGeometry() const = 0;

        /// \brief 设置TTF文字几何化
        /// \param bAsGeometry true几何化
        virtual void SetTTFTextAsGeometry(bool bAsGeometry) = 0;

        /// \brief 得到TTF文字是否几何化
        /// \return 返回TTF文字是否几何化
        virtual bool GetTTFTextAsGeometry() const = 0;        
#pragma endregion
        /// \brief 克隆一份导出设置对象
        /// 
        /// \return 返回克隆的导出设置对象
        virtual OwnerPtr<IPDFExportParams> Clone() const = 0;

        /// \brief 设置图形旋转角度
        /// \param plotRotation 旋转角度。复用PDFPlotRotation枚举，具体含义：Degrees0-不旋转 Degrees90-顺时针旋转90 Degrees180-顺时针旋转180度 Degrees270-顺时针旋转270度
        /// \return 以原点为基点，Z轴正向为旋转轴的旋转矩阵
        virtual gcmp::Matrix4d SetDrawingRotation(const PDFPlotRotation& angle) = 0;

        /// \brief 得到图形旋转角度
        /// \return 旋转角度（弧度）。逆时针为正，顺时针为负
        virtual PDFPlotRotation GetDrawingRotation() const = 0;

    public:
        virtual ~IPDFExportParams();
    };

}